﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Rabbit.Model;
using Rabbit.Controls;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Threading;
using Rabbit.BusinessLogicLayer;
using Rabbit.Utils;
using System.Windows.Media.Animation;
using System.Diagnostics;

namespace MicroBlogClient
{
    /// <summary>
    /// Interaction logic for CommentOperator.xaml
    /// </summary>
    public partial class CommentOperator : Window
    {
        public Status CurrentStatus
        {
            get { return (Status)GetValue(CurrentStatusProperty); }
            set { SetValue(CurrentStatusProperty, value); }
        }

        private StatusCommentBL statusCommentBL;

        // Using a DependencyProperty as the backing store for CurrentStatus.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentStatusProperty =
            DependencyProperty.Register("CurrentStatus", typeof(Status), typeof(CommentOperator), new UIPropertyMetadata(null));

        public Comment CurrentComment
        {
            get { return (Comment)GetValue(CurrentCommentProperty); }
            set { SetValue(CurrentCommentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CurrentComment.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentCommentProperty =
            DependencyProperty.Register("CurrentComment", typeof(Comment), typeof(CommentOperator), new UIPropertyMetadata(null));

        public bool IsReplyToComment
        {
            get { return (bool)GetValue(IsReplyToCommentProperty); }
            set { SetValue(IsReplyToCommentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsReplyToComment.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsReplyToCommentProperty =
            DependencyProperty.Register("IsReplyToComment", typeof(bool), typeof(CommentOperator), new UIPropertyMetadata(false));
        
        public bool IsReplyToStatus
        {
            get { return (bool)GetValue(IsReplyToStatusProperty); }
            set { SetValue(IsReplyToStatusProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsReplyToStatus.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsReplyToStatusProperty =
            DependencyProperty.Register("IsReplyToStatus", typeof(bool), typeof(CommentOperator), new UIPropertyMetadata(false));

        public string InitializedTextBoxContent
        {
            get { return (string)GetValue(InitializedTextBoxContentProperty); }
            set { SetValue(InitializedTextBoxContentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for InitializedTextBoxContent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty InitializedTextBoxContentProperty =
            DependencyProperty.Register("InitializedTextBoxContent", typeof(string), typeof(CommentOperator), new UIPropertyMetadata(string.Empty));

         
        public bool IsOperateOrignalStatus
        {
            get { return (bool)GetValue(IsOperateOrignalStatusProperty); }
            set { SetValue(IsOperateOrignalStatusProperty, value); }
        }

        ObservableCollection<Comment> CommentCollection = new ObservableCollection<Comment>();
        // Using a DependencyProperty as the backing store for IsOperateOrignalStatus.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsOperateOrignalStatusProperty =
            DependencyProperty.Register("IsOperateOrignalStatus", typeof(bool), typeof(CommentOperator), new UIPropertyMetadata(false));

        public bool IsCommentListVisible
        {
            get { return (bool)GetValue(IsCommentListVisibleProperty); }
            set { SetValue(IsCommentListVisibleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsCommentListVisible.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsCommentListVisibleProperty =
            DependencyProperty.Register("IsCommentListVisible", typeof(bool), typeof(CommentOperator), new UIPropertyMetadata(false));

        public string RepliedString
        {
            get { return (string)GetValue(RepliedStringProperty); }
            set { SetValue(RepliedStringProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RepliedString.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RepliedStringProperty =
            DependencyProperty.Register("RepliedString", typeof(string), typeof(CommentOperator), new UIPropertyMetadata(string.Empty));

        public string RepliedUserName
        {
            get { return (string)GetValue(RepliedUserNameProperty); }
            set { SetValue(RepliedUserNameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RepliedUserName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RepliedUserNameProperty =
            DependencyProperty.Register("RepliedUserName", typeof(string), typeof(CommentOperator), new UIPropertyMetadata(string.Empty));
         
        public bool IsForwardStatus
        {
            get { return (bool)GetValue(IsForwardStatusProperty); }
            set { SetValue(IsForwardStatusProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsForwardStatus.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsForwardStatusProperty =
            DependencyProperty.Register("IsForwardStatus", typeof(bool), typeof(CommentOperator), new UIPropertyMetadata(false));
         
        public string ProcessingTip
        {
            get { return (string)GetValue(ProcessingTipProperty); }
            set { SetValue(ProcessingTipProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ProcessingTip.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ProcessingTipProperty =
            DependencyProperty.Register("ProcessingTip", typeof(string), typeof(CommentOperator), new UIPropertyMetadata(string.Empty));

        public int CommentsCount
        {
            get { return (int)GetValue(CommentsCountProperty); }
            set { SetValue(CommentsCountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CommentsCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CommentsCountProperty =
            DependencyProperty.Register("CommentsCount", typeof(int), typeof(CommentOperator), new UIPropertyMetadata(0));


        private CommentOperator()
        {
            InitializeComponent();
            DataContext = this;
        }
        private static readonly CommentOperator instance = new CommentOperator();
        public static CommentOperator GetInstance()
        {
           ClearValue();
           return instance;
        }

        private static void ClearValue()
        {
             instance.ClearValue(CommentOperator.CurrentCommentProperty);
            instance.ClearValue(CommentOperator.CurrentStatusProperty);
            instance.ClearValue(CommentOperator.IsReplyToStatusProperty);
            instance.ClearValue(CommentOperator.IsReplyToCommentProperty);
            instance.ClearValue(CommentOperator.IsOperateOrignalStatusProperty);
            instance.ClearValue(CommentOperator.InitializedTextBoxContentProperty);
            instance.ClearValue(CommentOperator.IsCommentListVisibleProperty);
            instance.ClearValue(CommentOperator.IsForwardStatusProperty);
            instance.ClearValue(CommentOperator.ProcessingTipProperty);
            instance.ClearValue(CommentOperator.HeightProperty);
            instance.CommentCollection.Clear();
            instance.lstComment.ItemsSource = instance.CommentCollection;
            (instance.FindResource("StoryBoardPopupAnimation") as Storyboard).Stop();
            instance.SetCurrentValue(Window.OpacityProperty, 1.0);
            instance.SetCurrentValue(Window.VisibilityProperty,Visibility.Visible);
        }

        private void btnTitleBarClose_Click(object sender, RoutedEventArgs e)
        {
            this.Hide();
        }

        private void HideMe()
        {
            this.Dispatcher.BeginInvoke(new Action(
                    () => 
                        (this.FindResource("StoryBoardPopupAnimation") as Storyboard).Begin()));
        }

        protected void link_OnUserNameClicked(object sender, RoutedEventArgs e)
        {
            Hyperlink link = sender as Hyperlink;
            if (link == null)
            {
                link = e.OriginalSource as Hyperlink;
            }
            (Application.Current.MainWindow as MainWindow).OpenUserStatusByName(link.CommandParameter.ToString());
        }

        protected void statusImage_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            ImageEx img = sender as ImageEx;
            if (img != null)
            {
                PictureViewer pv = new PictureViewer();
                pv.PictureSource = img.LargerPictureSource;
                pv.ShowActivated = true;
                pv.Show();
            }
            e.Handled = true;
        }

        protected void menuCopyStatus_Click(object sender, RoutedEventArgs e)
        {
            string text = (sender as MenuItem).CommandParameter.ToString();
            Clipboard.SetText(text);
        }

         
        private void Window_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.Source is Canvas || e.Source is TextBlock)
            {
                base.DragMove();
            }
        }

        public void ShowAndActivate(Win32.POINT point)
        {
            double left = point.x;
            double top = point.y;

            if (left> SystemParameters.FullPrimaryScreenWidth - this.ActualWidth)
            {
                left = SystemParameters.FullPrimaryScreenWidth - this.ActualWidth - 20;
            }
            if (top > SystemParameters.FullPrimaryScreenHeight - this.ActualHeight)
            {
                top = SystemParameters.FullPrimaryScreenHeight - this.ActualHeight-20;
            }

            if (top<=0)
            {
                top = 0;
            }
            if (left<=0)
            {
                left = 0;
            }
            this.Left =left;
            this.Top = top;
            if (!this.IsActive)
            {
                this.Show();
                this.Activate();
                InitializeReplyString();
                txtReply.Focus();
            }
        }

        private void InitializeReplyString()
        {
            if (IsReplyToStatus || IsForwardStatus)
            {
                if (IsOperateOrignalStatus)
	            {
                    RepliedString = CurrentStatus.InReplyToStatusText;
                    RepliedUserName = CurrentStatus.InReplyToScreenName;
                    CommentsCount = CurrentStatus.InReplyToCommentsCount;
	            }
                else 
                {
                    RepliedString = CurrentStatus.Text;
                    RepliedUserName = CurrentStatus.User.ScreenName;
                    CommentsCount = CurrentStatus.CommentsCount;
                }
            }

            if (IsForwardStatus)
            {
                InitializedTextBoxContent = string.Format("//@{0}",
                    IsOperateOrignalStatus ? CurrentStatus .InReplyToScreenName: CurrentStatus.User.ScreenName);

                if (!IsOperateOrignalStatus && CurrentStatus.InReplyToStatusId != 0)
                {
                    InitializedTextBoxContent += " " + CurrentStatus.Text;
                }
            }

            InitializedTextBoxContent = InitializedTextBoxContent.Length >= txtReply.MaxLength ?
                InitializedTextBoxContent.Substring(0, txtReply.MaxLength - 30) + "..." : InitializedTextBoxContent;

            if (IsReplyToComment)
            {
                RepliedString = CurrentComment.Text;
                RepliedUserName = CurrentComment.User.ScreenName;
            }
        }

        private void ReplyToCommentsHandler(object sender, RoutedEventArgs e)
        {
            Comment comment = Rabbit.Utils.Common.GetListBoxItemFromChild((sender as Hyperlink).Parent as DependencyObject).Content as Comment;

            comment.InReplyToStatusId = IsOperateOrignalStatus? CurrentStatus.InReplyToStatusId : CurrentStatus.Id;

            //InitializedTextBoxContent = "@" + comment.User.ScreenName;
            txtReply.Focus();
            IsReplyToComment = true;
            IsReplyToStatus = false;
            IsForwardStatus = false;
            CurrentComment = comment;
        }

        private void linkShowComments_Click(object sender, RoutedEventArgs e)
        {
            if (IsReplyToStatus)
            {
                bool isNoComment = false;
                if (IsOperateOrignalStatus && CurrentStatus.InReplyToCommentsCount ==0)
                {
                    isNoComment = true;
                }

                if (IsOperateOrignalStatus == false && CurrentStatus.CommentsCount==0)
                {
                    isNoComment = true;
                }

                if (isNoComment)
                {
                    MessageBox.Show("暂无评论,快抢沙发");
                    return;
                }

                LoadComment();
            }
        }


        private void LoadComment()
        {
            long statusID = CurrentStatus.Id;
            statusCommentBL = new StatusCommentBL();
            ProcessingTip = "加载中...";

            if (IsOperateOrignalStatus)
	        {
              statusID = CurrentStatus.InReplyToStatusId;
	        }

            statusCommentBL.StatusID = statusID;

            Action fetchingComments = () =>
                {
                    try
                    {
                        List<Comment> commentList = statusCommentBL.GetFirstPageComment();
                        FillCommentList(commentList); 
                    }
                    catch (Exception)
                    {
                        ProcessingTip = "加载失败";
                    }
                };

            fetchingComments.BeginInvoke(null, null);
        }

        private void UCPager_OnFirstPageClick(object sender, RoutedEventArgs e)
        {
            LoadComment();
        }

        private void UCPager_OnNextPageClick(object sender, RoutedEventArgs e)
        {
            ProcessingTip = "加载中...";
            Action fetchingComments = () =>
            {
                try
                {
                    List<Comment> commentList = statusCommentBL.GetNextPageComment();
                    FillCommentList(commentList);
                }
                catch (Exception)
                {
                    ProcessingTip = "加载失败";
                }
            };

            fetchingComments.BeginInvoke(null, null);
        }

        private void UCPager_OnPreviousePage(object sender, RoutedEventArgs e)
        {
            ProcessingTip = "加载中...";
            Action fetchingComments = () =>
            {
                try
                {
                    List<Comment> commentList = statusCommentBL.GetPreviousePageComment();
                    FillCommentList(commentList);
                }
                catch (Exception)
                {
                    ProcessingTip = "加载失败";
                }
            };

            fetchingComments.BeginInvoke(null, null);
        }

        private void FillCommentList(List<Comment> source)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                CommentCollection.Clear();
                source.ForEach(c => CommentCollection.Add(c));
                if (CommentCollection.Count>0)
                {
                    lstComment.ScrollIntoView(CommentCollection[0]);
                }
                this.IsCommentListVisible = true;
                ProcessingTip = "";
                ucPager.CanNextPageClick = statusCommentBL.CanGetNextPage;
                ucPager.CanPreviousePageClick = statusCommentBL.CanGetPreviousePage;
            }
           ));
        }

        private void btnPublish_Click(object sender, RoutedEventArgs e)
        {
            if (IsReplyToComment)
            {
                ReplyToComment();
            }

            if (IsReplyToStatus)
            {
                ReplyToStatus();
            }

            if (IsForwardStatus)
            {
                ForwardStatus();
            }
        }

        private void ReplyToComment()
        {
            if (string.IsNullOrEmpty(InitializedTextBoxContent))
            {
                ProcessingTip = "回复内容不可为空";
                return;
            }

            string text = InitializedTextBoxContent;
            long statusID = CurrentComment.InReplyToStatusId;
            long userID = CurrentComment.User.Id;

            Debug.Print("text:" + text);
            Action replyorFoward = () =>
            {
                try
                {
                    StatusesBL.ReplyToComment(text,statusID , userID);
                    ShowMessage("回复成功");
                    HideMe();
                }
                catch (PublishAPICallTooFrequentException)
                {
                    ShowMessage("您操作太频繁了，休息一下");
                }
                catch (Exception ex)
                {
                    LogHelper.LogError(ex);
                    ShowMessage("回复失败");
                }
            };

            replyorFoward.BeginInvoke(null, null);
        }

        private void ShowMessage(string text)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                ProcessingTip = text;
            }
            ));
        }

        private void ReplyToStatus()
        {
            if (string.IsNullOrEmpty(InitializedTextBoxContent))
            {
                ProcessingTip = "评论内容不可为空";
                return;
            }
            ShowMessage("正在评论..");
            string text = InitializedTextBoxContent;
            long statusID = IsOperateOrignalStatus ? CurrentStatus.InReplyToStatusId : CurrentStatus.Id;
            long userID = IsOperateOrignalStatus ? CurrentStatus.InReplyToUserId : CurrentStatus.User.Id;
            Debug.Print("评论内容text:" + text);

            Action replyorFoward = () =>
            {
                try
                {
                    StatusesBL.ReplyToStatus(text, statusID);
                    this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        if (IsOperateOrignalStatus)
                        {
                            CurrentStatus.InReplyToCommentsCount += 1;
                        }
                        else
                        {
                            CurrentStatus.CommentsCount += 1;
                        }
                        HideMe();
                    }));

                    ShowMessage("评论成功");
                }
                catch (PublishAPICallTooFrequentException)
                {
                    ShowMessage("您操作太快了，休息一下");
                }
                catch (Exception ex)
                {
                    LogHelper.LogError(ex);
                    ShowMessage("评论失败");
                }
            };
            replyorFoward.BeginInvoke(null, null);
        }

        private void ForwardStatus()
        {
            bool IsCommentOrignalStatus = (bool)chkCommentOrignalStatus.IsChecked;
            ShowMessage("正在转发..");
            string text = InitializedTextBoxContent;
            long statusID = IsOperateOrignalStatus ? CurrentStatus.InReplyToStatusId : CurrentStatus.Id;
            long userID = IsOperateOrignalStatus ? CurrentStatus.InReplyToUserId : CurrentStatus.User.Id;

            Debug.Print("评论内容text:" + text);
            Action replyorFoward = () =>
            {
                try
                {
                    Status status = StatusesBL.ForwardStatus(
                        statusID,
                        text,
                        IsCommentOrignalStatus);

                    this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        if (IsOperateOrignalStatus)
                        {
                            CurrentStatus.InReplyToTransmitCount += 1;
                            status.InReplyToTransmitCount = CurrentStatus.InReplyToTransmitCount;
                        }
                        else
                        {
                            CurrentStatus.TransmitCount += 1;
                            status.InReplyToTransmitCount = CurrentStatus.TransmitCount;
                        }
                        ((Application.Current.MainWindow as MainWindow).frmFriendsStatus.Content as PageBase).DoWork(status);
                        HideMe();
                    }));
                    ShowMessage("转发成功");
                }
                catch (PublishAPICallTooFrequentException)
                {
                    ShowMessage("您操作太频繁了，休息一下");
                }
                catch (Exception ex)
                {
                    LogHelper.LogError(ex);
                    ShowMessage("转发失败，请重试");
                }
            };
            replyorFoward.BeginInvoke(null, null);
        }

        private void txtReply_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (!btnPublish.IsEnabled)
            {
                return;
            }

            if (e.Key == Key.Escape)
            {
                txtReply.Clear();
            }
            else if (e.KeyStates == Keyboard.GetKeyStates(Key.Enter)
               && Keyboard.Modifiers == ModifierKeys.Control
               )
            {
                //if Ctrl+Enter pressed,call btnPublishStatus_click to publish the status
                btnPublish_Click(null, null);
            }
        }
    }
}
